#ifndef MKAHYPAR_INITIAL_PARTITIONER_BASE_H
#define MKAHYPAR_INITIAL_PARTITIONER_BASE_H
#include "mkahypar/utils/mandatory.h"
#include "mkahypar/utils/typedef.h"
#include "mkahypar/partition/context.h"
#include "mkahypar/utils/randomize.h"
namespace mkahypar{
  template <typename Derived = Mandatory>
  class InitialPartitionerBase{
  public:

    InitialPartitionerBase(Hypergraph& hypergraph, TargetGraph& targetGraph):
    _hg(hypergraph),_topo(targetGraph),
    _node_assigned(hypergraph.initialNumNodes()){

    }
    InitialPartitionerBase(const InitialPartitionerBase&) = delete;
    InitialPartitionerBase& operator= (const InitialPartitionerBase&) = delete;

    InitialPartitionerBase(InitialPartitionerBase&&) = default;
    InitialPartitionerBase& operator= (InitialPartitionerBase&&) = delete;

    virtual ~InitialPartitionerBase() = default;

    //多次运行初始划分
    void singleRunsInitialPartitioning(){
      static_cast<Derived*>(this)->initialPartition();
    }

    //单次运行初始划分
    void multipleRunsInitialPartitioning(){
      GainType best_obj = std::numeric_limits<GainType>::max();
      std::vector<PartitionID> best_partition(_hg.initialNumNodes(), 0);
      //调用实际的划分方法
      static_cast<Derived*>(this)->initialPartition();

    }


    //加入顶点到id,hn必须是非法分区
    void setNodePart(const HypernodeID hn, const PartitionID id) {
      if(_hg.hypernode(hn).part_id != Hypergraph::kInvalidPartition)
        ERROREXIT("error!must valid part!");

      _topo._fpga[id]._used_res += _hg.hypernode(hn).weight();
      _hg.hypernode(hn).part_id = id;
      for (const HyperedgeID &he: _hg.incidentEdges(hn)) {
        _hg.incrementPinCountInPart(he, id);
        if(_hg.hyperedge(he).source() != hn)
          _hg.incrementRouteCountInPart(he,id,hn);
      }
    }
    //初始化切割
    void initializeNumCutHyperedges(){

    }


    Hypergraph & _hg;
    TargetGraph & _topo;
    ds::FastResetFlagArray<HypernodeID>_node_assigned;//标记顶点是否被放置

  };
}
#endif //MKAHYPAR_INITIAL_PARTITIONER_BASE_H
